import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Scanner;

public class FileAccess {
	
	FileReader fileReader;
	BufferedReader bufferedReader;
	String str;
	String[] temp;
	String[] temp2;
	String[] headerArray;
	boolean flag = true;
	ArrayList<datatype> types = new ArrayList<datatype>();
	datatype[] datatypes = new datatype[7];
	BufferedWriter bufferedWriter;
	datatype header=new datatype();
	ArrayList<String> headerFile_types = new ArrayList<String>();
	ArrayList<Integer> indexPresent;
	IndexPresent list = new IndexPresent();
	boolean matched=true;
	IndexHeader indexHeader = new IndexHeader();
	static index indexes[] = null ;
	/*
	 * Function to insert record into the heap file.
	 */
	public void readFile(String path)
	{
		//System.out.println("Print File");
		datatypes[0] = new i1();
		datatypes[1] = new i2();
		datatypes[2] = new i4();
		datatypes[3] = new i8();
		datatypes[4] = new r4();
		datatypes[5] = new r8();
		datatypes[6] = new cx();
		boolean debug = false;
		// Will give an exception if the heap file is not already present
		try{
			if(heap.created)
			{

			ReadHeader reader = new ReadHeader();		
			temp2= reader.read(path);
			//System.out.println(temp2.length);
			String t1[] = new String [temp2.length-1];
			for(int r=0;r<t1.length;r++)
			{
				t1[r] = temp2[r];
			}
			indexPresent = list.indexPresentList(t1, path);
			if(debug)
			{
			for(int l : indexPresent)
			System.out.println(l+ "Index");
			}
			for(int k=0;k<temp2.length-1;k++)
				{
				//System.out.println(temp2[k]);
				headerFile_types.add(temp2[k]);
				//System.out.println(headerFile_types.get(k));
				}
			/*for (int i=0;i<headerFile_types.size();i++)
				System.out.print(i+"\t"+ headerFile_types.get(i)+"\t");
			System.out.println();
				
				*/
			heap.created=false;
			
			}
		}
			
		catch (Exception e) 
		{
			heap.f=new File(path);

		}
		
		heap.f=new File(path);
		
		//create an index
		Scanner in = new Scanner(System.in);
		//System.out.println(heap.created);
		//System.out.println(flag);
		/*
		 * Reading the header and comparing it with input csv file's schema 
		 * and inserting records if the two match.
		 */
		try 
		{	
			
			
			/*File f = new File("input_2.csv");
			BufferedReader br = new BufferedReader(new FileReader(f));
			String x="";
			while(( x =br.readLine())!=null)
			*/
			while((in.hasNext()))
			{
				
				String str = in.nextLine();
				
				//String str = x;
				
				temp = str.split(",");
				
				if(flag)
				{
					indexes = new index[temp.length];
					types = convertHeader.convertHeader(temp);
					
					if(heap.created)
					{
							///System.out.println("Index out");
							indexPresent = list.indexPresentList(temp, path);
							str=str+","+heap.recordlength;
							header.write(str.length()+","+str,0);
							int y = path.indexOf(".");
							String fileName = path.substring(0, y);
							
							for(int k = 0; k < indexPresent.size(); k++)
							{
								long[] details = new long[6];
								details[0] = 1;
								details[1] = 1;
								details[2] = 0;
								details[3] = types.get(indexPresent.get(k)-1).length + 8;
							    details[4] = Long.MAX_VALUE;
							    details[5] = 0;
								indexes[indexPresent.get(k)-1] = new index(details);
								//System.out.println("Heap.created" + indexes[indexPresent.get(k)-1]);
								File file = new File(fileName+"."+indexPresent.get(k)+".lho");
								File file2 = new File(fileName+"."+indexPresent.get(k)+".lht");
								indexes[indexPresent.get(k)-1].fo=file;
								indexes[indexPresent.get(k)-1].ft=file2;
								indexHeader.writeHeader(indexes[indexPresent.get(k)-1],details);	
							}
							//System.out.println("for");
					}
					else
					{
						for(int m =0; m <indexPresent.size(); m++)
						{
							int y = path.indexOf(".");
							String fileName = path.substring(0, y);
							File file = new File(fileName+"."+indexPresent.get(m)+".lho");
							File file2 = new File(fileName+"."+indexPresent.get(m)+".lht");
							long[] details;
							try 
							{
							//	System.out.println("RASCAL"+ (indexPresent.get(m)-1));
								//System.out.println("Details");
								details = indexHeader.readHeader(file);
								//for(long p : details)
							//	System.out.print(p+ "\t");
								//System.out.println();
								indexes[(indexPresent.get(m)-1)] = new index(details);
								indexes[(indexPresent.get(m)-1)].fo=file;
								indexes[(indexPresent.get(m)-1)].ft=file2;
							//	System.out.println("index" + indexes[0]);
						} 
							catch (Exception e) 
							{
								e.printStackTrace();
							}
							
						}
					}
						
					if (headerFile_types.size()==0)
						matched = true;
					
					
					else if(temp.length==headerFile_types.size() )
					{
						for(int i=0;i<temp.length;i++)
						{
							//System.out.println(temp[i] + "\t" + headerFile_types.get(i));
							if(!temp[i].equalsIgnoreCase(headerFile_types.get(i)))
							{
								matched=false;
								break;
							}
						}
					}
					else
					{
						//System.out.println(temp.length + "\t" + headerFile_types.size());
						matched=false;
					}
					
					flag = false;
					
				}
				
				else if (matched & !flag)
				{
					//System.out.println(types.get(j).type);
					//System.out.println(" Inside flag");
					long readPointer=0;
					for(int j = 0; j < temp.length; j++ )
					{
						//System.out.println(j);
						if(j==0)
							readPointer=heap.f.length();
						if(indexPresent.size()>0)
						{
							if(indexPresent.contains(j+1))
							{
								if(types.get(j).type==6)
								{
									for(int i=temp[j].length();i<types.get(j).length;i++)
										temp[j]+='~';
								}
							indexes[j].updateIndex(temp[j], readPointer, types, j);
							}
						}
						/*System.out.println("Heap File Length:    "+heap.f.length());
						System.out.println(j+"              "+temp[j]);
						System.out.println("..............: "+types.get(j).type);*/
						datatypes[types.get(j).type].write(temp[j],types.get(j).length);
						
					}
				}
				
			}
			if (matched==false)
				System.out.println("Incompatible types!!!!");
			
			IndexHeader ih = new IndexHeader();
			for(int i =0;i< indexPresent.size();i++)
			{
				index z = indexes[indexPresent.get(i)-1];
				ih.writeHeader(z);
			}
			
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
	}
}
